#include "StdAfx.h"
#include "Communication.h"
#include "Form1.h"


using namespace System;
using namespace System::IO;
using namespace System::Net;
using namespace System::Text;
using namespace System::Net::Sockets;
using namespace System::Collections;
using namespace ARDroneCom;


Communication::Communication(void)
{

	/*Building up AT Socket*/
	Communication::ATEndPoint = gcnew System::Net::IPEndPoint(IPAddress::Parse(DRONE_IP) , AT_PORT );
	Communication::ATSock = gcnew Socket(	ATEndPoint->AddressFamily, 
											Net::Sockets::SocketType::Dgram, 
											Sockets::ProtocolType::Udp
										);

	/*Building up  NavDataSocket and bind Port to Socket for receive-Methods*/
	Communication::NavDataEndPoint = gcnew System::Net::IPEndPoint(IPAddress::Parse(DRONE_IP) , NAV_DATA_PORT );
	Communication::NavDataSock = gcnew Socket(	NavDataEndPoint->AddressFamily, 
												Net::Sockets::SocketType::Dgram, 
												Sockets::ProtocolType::Udp
											);


	/*Building up  VideoSocket*/
	Communication::VideoEndPoint = gcnew System::Net::IPEndPoint(IPAddress::Parse(DRONE_IP) , VIDEO_PORT );
	Communication::VideoSock = gcnew Socket(	VideoEndPoint->AddressFamily, 
												Net::Sockets::SocketType::Dgram, 
												Sockets::ProtocolType::Udp
											);	
	//
	//Net::EndPoint^ localEp = safe_cast<EndPoint^>(NavDataEndPoint); //typecast for bind()
	//if(NavDataEndPoint && NavDataSock) NavDataSock->Bind(localEp);
}

/*Getter-Methods for aquire Sockets and EndPoints*/
Socket^ Communication::getATSock(){
	return(this->ATSock);
}

Socket^ Communication::getNavDataSock(){
	return(this->NavDataSock);
}

Socket^ Communication::getVideoSock(){
	return(this->VideoSock);
}

IPEndPoint^ Communication::getATEndpoint(){
	return(this->ATEndPoint);
}

IPEndPoint^ Communication::getNavDataEndpoint(){
	return(this->NavDataEndPoint);
}

IPEndPoint^ Communication::getVideoEndpoint(){
	return(this->VideoEndPoint);
}




int Communication::Connect(Socket^ sock, IPEndPoint^ EndPoint){
	int retry=0;

	if((sock==nullptr)||(EndPoint==nullptr)) return -1;
	else{
		sock->Connect(EndPoint);
	}

	while(!sock->Connected){
		sock->Connect(EndPoint);
		retry++;
		
		if(retry==4) return -1; //kein Erfolg nach 4 Versuchen
		System::Threading::Thread::Sleep(1000);
	}
	return 1;
}

int Communication::Disconnect(System::Net::Sockets::Socket^ sock){

	if(sock==nullptr) return -1;
	else{
		sock->Close();
	return 1;
	}
}

int Communication::sendString(wchar_t *buffer){

	String^ MSG = gcnew String(buffer);

	array<Byte>^ msg = Encoding::ASCII->GetBytes( MSG ); 
	try {
		getATSock()->SendTo(msg,getATEndpoint()); 
		return 1;
		} catch (...) {
		return -1;	
	}
}

String^ Communication::receiveString(Socket^ Sock){
	cli::array<unsigned char>^ buffer = gcnew cli::array<unsigned char>(256);
	buffer->Initialize();
	if((Sock!=nullptr)&&(Sock->IsBound)){
		try{
			Sock->Receive(buffer, 256,SocketFlags::None);
		}catch(...){
		//	buffer->Copy("!ERROR!",buffer,7);
		}
	return(buffer->ToString());
	}else{
		return("!Error! - Socket nullPointer or Socket not bound");
	}
}